package com.shanzmoo.db.stm.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shanzmoo.base.bean.SResponse;
import com.shanzmoo.base.constant.Constant;
import com.shanzmoo.db.stm.entity.StmSysMenuEntity;
import com.shanzmoo.db.stm.entity.vo.StmSysMenuVO;
import com.shanzmoo.db.stm.entity.query.StmSysMenuQuery;
import com.shanzmoo.db.stm.mapper.StmSysMenuMapper;
import com.shanzmoo.db.stm.service.IStmSysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shanzmoo.db.sys.entity.MenuEntity;
import com.shanzmoo.db.sys.entity.vo.MenuTreeVo;
import com.shanzmoo.db.sys.entity.vo.MenuVo;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 仓储用户系统菜单 服务实现类
 *
 * @author Gzhao 2021-03-10
 */
@Service
public class StmSysMenuServiceImpl extends ServiceImpl<StmSysMenuMapper, StmSysMenuEntity>
        implements IStmSysMenuService {

    @Override
    public List<StmSysMenuVO> queryPageList(StmSysMenuQuery query) {
        return baseMapper.queryPageList(query);
    }

    @Override
    public SResponse<Boolean> deleteById(Integer id, Integer userId) {
        StmSysMenuEntity menuEntity = new StmSysMenuEntity();
        menuEntity.setMenuId(id);
        menuEntity.setDeleted(true);
        menuEntity.setUpdateUser(userId);

        List<StmSysMenuEntity> children = baseMapper.selectList(
                new QueryWrapper<StmSysMenuEntity>()
                        .eq("deleted", false)
                        .eq("parent_id", id)
        );
        if (CollUtil.isNotEmpty(children)) {
            return SResponse.fail(Constant.ERRCODE_LOGIC, "请确认当前菜单没有子菜单后再删除！");
        }

        int re = baseMapper.updateById(menuEntity);
        if (re > 0) {
            return SResponse.ok();
        }

        return SResponse.fail(Constant.ERRCODE_DATABASE_OPERATION, "菜单不存在，删除失败");
    }

    @Override
    public SResponse<List<MenuVo>> getAllTree() {
        List<StmSysMenuEntity> allList = baseMapper.selectList(
                new QueryWrapper<StmSysMenuEntity>()
                        .eq("deleted", false)
        );
        if (CollUtil.isEmpty(allList)) {
            return SResponse.ok(Collections.emptyList());
        }

        // 一级目录
        List<MenuVo> firstLevelMenu = allList.stream()
                .filter(e -> 0 == e.getParentId())
                .map(MenuVo::create)
                .sorted(Comparator.comparingInt(MenuVo::getMenuIndex))
                .collect(Collectors.toList());

        firstLevelMenu.forEach(root -> {
            findChildren(root, allList);
        });

        return SResponse.ok(firstLevelMenu);
    }

    @Override
    public SResponse<List<MenuTreeVo>> getBriefTree() {
        List<StmSysMenuEntity> allList = baseMapper.selectList(
                new QueryWrapper<StmSysMenuEntity>()
                        .eq("deleted", false)
        );

        // 菜单只到二级
        if (CollUtil.isEmpty(allList)) {
            return SResponse.ok(Collections.EMPTY_LIST);
        }
        // 目录
        List<MenuTreeVo> firstLevelMenu = allList.stream()
                .filter(e -> e.getMenuType() == 0)
                .map(MenuTreeVo::create)
                .collect(Collectors.toList());

        firstLevelMenu.forEach(e -> {
            // 二级
            List<MenuTreeVo> secondLevelMenuList = allList.stream()
                    .filter(child -> Objects.equals(child.getParentId(), e.getMenuId())
                            && child.getMenuType() == 1)
                    .map(MenuTreeVo::create)
                    .collect(Collectors.toList());

            if (CollectionUtil.isEmpty(secondLevelMenuList)) {
                return;
            }

            e.setChildren(secondLevelMenuList);
            secondLevelMenuList.forEach(secondMenu -> {
                // 三级
                List<MenuTreeVo> thridLevelMenuList = allList.stream()
                        .filter(child -> Objects.equals(child.getParentId(), secondMenu.getMenuId())
                                && child.getMenuType() == 1)
                        .map(obj -> {
                            return MenuTreeVo.create(obj);
                        }).collect(Collectors.toList());
                secondMenu.setChildren(CollectionUtil.isNotEmpty(thridLevelMenuList) ? thridLevelMenuList : null);
                thridLevelMenuList.forEach(thridMenu -> {
                    // 四级
                    List<MenuTreeVo> buttonList = allList.stream()
                            .filter(child -> Objects.equals(child.getParentId(), thridMenu.getMenuId())
                                    && child.getMenuType() == 2)
                            .map(MenuTreeVo::create)
                            .collect(Collectors.toList());
                    thridMenu.setChildren(CollectionUtil.isNotEmpty(buttonList) ? buttonList : null);
                });
            });
        });
        return SResponse.ok(firstLevelMenu);
    }

    @Override
    public List<StmSysMenuEntity> getListByUserId(Integer memberId) {
        return baseMapper.getListByUserId(memberId);
    }

    private void findChildren(MenuVo root, List<StmSysMenuEntity> allList) {
        List<MenuVo> children = allList.stream()
                .filter(child -> Objects.equals(child.getParentId(), root.getMenuId()))
                .map(MenuVo::create)
                .sorted(Comparator.comparingInt(MenuVo::getMenuIndex))
                .collect(Collectors.toList());

        // 没有子菜单，跳出循环
        if (CollectionUtil.isEmpty(children)) {
            return;
        }

        children.forEach(child -> {
            findChildren(child, allList);
        });

        root.setChildren(children);
    }
}
